package com.ruoyi.business.controller;

import com.ruoyi.business.domain.Grade;
import com.ruoyi.business.service.IGradeService;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.SecurityUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.annotations.ApiIgnore;

import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.business.domain.ScoringStandard;
import com.ruoyi.business.service.IScoringStandardService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * 评分标准Controller
 * 
 * @author lcz
 * @date 2025-03-31
 */
@Api(tags = "评分标准相关接口")
@RestController
@RequestMapping("/business/scoringStandard")
public class ScoringStandardController extends BaseController
{
    @Autowired
    private IScoringStandardService scoringStandardService;

    @Autowired
    private IGradeService gradeService;

    /**
     * 查询评分标准列表
     */
    @ApiOperation(value = "后台----查询评分标准列表")
//    @PreAuthorize("@ss.hasPermi('business:scoringStandard:list')")
    @GetMapping("/list")
    public TableDataInfo list(ScoringStandard scoringStandard)
    {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        if (!ObjectUtils.isEmpty(sysUser.getSchoolId())){
            scoringStandard.setSchoolId(sysUser.getSchoolId());
        }
        startPage();
        List<ScoringStandard> list = scoringStandardService.selectScoringStandardList(scoringStandard);
        return getDataTable(list);
    }

    /**
     * 导出评分标准列表
     */
    @ApiOperation(value = "后台----导出评分标准列表")
//    @PreAuthorize("@ss.hasPermi('business:scoringStandard:export')")
    @Log(title = "评分标准", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, ScoringStandard scoringStandard)
    {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        if (!ObjectUtils.isEmpty(sysUser.getSchoolId())){
            scoringStandard.setSchoolId(sysUser.getSchoolId());
        }
        List<ScoringStandard> list = scoringStandardService.exportList(scoringStandard);
        ExcelUtil<ScoringStandard> util = new ExcelUtil<ScoringStandard>(ScoringStandard.class);
        util.exportExcel(response, list, "评分标准数据");
    }

    /**
     * 获取评分标准详细信息
     */
    @ApiOperation(value = "后台----获取评分标准详细信息")
//    @PreAuthorize("@ss.hasPermi('business:scoringStandard:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return success(scoringStandardService.selectScoringStandardById(id));
    }

    /**
     * 新增评分标准
     */
    @ApiOperation(value = "后台----新增评分标准")
//    @PreAuthorize("@ss.hasPermi('business:scoringStandard:add')")
    @Log(title = "评分标准", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody ScoringStandard scoringStandard)
    {
        return toAjax(scoringStandardService.insertScoringStandard(scoringStandard));
    }

    /**
     * 修改评分标准
     */
    @ApiOperation(value = "后台----修改评分标准")
//    @PreAuthorize("@ss.hasPermi('business:scoringStandard:edit')")
    @Log(title = "评分标准", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody ScoringStandard scoringStandard)
    {
        return toAjax(scoringStandardService.updateScoringStandard(scoringStandard));
    }

    /**
     * 删除评分标准
     */
    @ApiOperation(value = "后台----删除评分标准")
//    @PreAuthorize("@ss.hasPermi('business:scoringStandard:remove')")
    @Log(title = "评分标准", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        return toAjax(scoringStandardService.deleteScoringStandardByIds(ids));
    }

    /**
     * 导入接口
     */
    @ApiOperation("后台----导入评分标准")
    @PostMapping("/importScoringStandard")
    public AjaxResult importScoringStandard(MultipartFile file) throws Exception {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        if (ObjectUtils.isEmpty(sysUser.getSchoolId())){
            return AjaxResult.error("该用户没有归属机构，请先选择机构");
        }

        //获取该用户学校中的年级列表
        Grade gradeParam = new Grade();
        gradeParam.setSchoolId(sysUser.getSchoolId());
        List<Grade> gradeList = gradeService.selectGradeList(gradeParam);

        InputStream inputStream = file.getInputStream();
        ExcelUtil<ScoringStandard> util = new ExcelUtil<ScoringStandard>(ScoringStandard.class);
        List<ScoringStandard> scoringStandardList = util.importExcel(inputStream);

        //获取scoringStandardList中的所有年级ID
        Set<Long> gradeIdSet = scoringStandardList.stream().map(ScoringStandard::getGradeId).collect(Collectors.toSet());

        //判断gradeIdSet中的年级ID是否在gradeList中，如果不在，则返回错误信息
        for (Long gradeId : gradeIdSet) {
            if (!gradeList.stream().map(Grade::getId).collect(Collectors.toSet()).contains(gradeId)) {
                return AjaxResult.error("导入失败，请检查Excel文件中的年级ID是否正确");
            }
        }

        //TODO: 对scoringStandardList中的数据进行检查，以年级ID、项目ID、性别、成绩为组合键，找出scoringStandardList中是否存在组合键重复的数据，如果存在，则返回错误信息和重复的行号
        Map<String, Integer> duplicateCheckMap = new HashMap<>();
        List<Integer> tempNumbers = new ArrayList<>();

        for (int i = 0; i < scoringStandardList.size(); i++) {
            ScoringStandard scoringStandard = scoringStandardList.get(i);
            String key = scoringStandard.getGradeId() + "-" +
                    scoringStandard.getProjectId() + "-" +
                    scoringStandard.getGender() + "-" +
                    scoringStandard.getScore();

            if (duplicateCheckMap.containsKey(key)) {
                // 如果已存在该组合键，则当前行为重复数据
                // 记录重复的行号（Excel从1开始，假设i=0是第2行数据）
                if (duplicateCheckMap.get(key) != -1) {
                    tempNumbers.add(duplicateCheckMap.get(key) + 2); // 第一行为标题，所以+2
                    duplicateCheckMap.put(key, -1); // 标记为已记录
                }
                tempNumbers.add(i + 2); // 当前行号也加入
            } else {
                duplicateCheckMap.put(key, i); // 记录第一次出现的索引
            }
        }

        // 去重，避免同一组键多次报错重复
        tempNumbers = tempNumbers.stream().distinct().sorted().collect(Collectors.toList());

        if (!tempNumbers.isEmpty()) {
            return AjaxResult.error("导入失败：以下行号的数据重复了：" + tempNumbers);
        }

        ScoringStandard param = new ScoringStandard();
        param.setSchoolId(sysUser.getSchoolId());
        List<ScoringStandard> dataList = scoringStandardService.selectScoringStandardList(param);
        // TODO: 比较两个列表，以年级ID、项目ID、性别、成绩为组合键，找出scoringStandardList中有多少数据是dataList中存在的，并返回这些数据的行号

        // 用于存储重复数据的行号
        List<Integer> duplicateRowNumbers = new ArrayList<>();

        try {
            // 创建一个映射，用于快速查找dataList中是否存在相同的组合键
            Map<String, ScoringStandard> existingDataMap = dataList.stream()
                    .collect(Collectors.toMap(
                            ps -> ps.getGradeId() + "-" + ps.getProjectId() + "-" + ps.getGender() + "-" + ps.getScore(),
                            ps -> ps
                    ));

            // 遍历导入的scoringStandardList，检查是否存在重复数据
            for (int i = 0; i < scoringStandardList.size(); i++) {
                ScoringStandard scoringStandard = scoringStandardList.get(i);
                //  分数改为两位小数
                scoringStandard.setScore(scoringStandard.getScore().setScale(2));
                String key = scoringStandard.getGradeId() + "-" + scoringStandard.getProjectId() + "-" + scoringStandard.getGender() + "-" + scoringStandard.getScore();
                if (existingDataMap.containsKey(key)) {
                    // 如果存在重复，记录行号（注意：Excel行号从1开始，i从0开始，所以需要加2）
                    duplicateRowNumbers.add(i + 2); // 假设第一行为标题行
                }
            }
        } catch (Exception e) {
            return AjaxResult.error("导入失败,请检查:年级ID、项目ID、性别、成绩 是否为正确值");
        }

        // 如果有重复数据，返回错误信息和重复的行号
        if (!duplicateRowNumbers.isEmpty()) {
            return AjaxResult.error("以下行号的数据已存在：" + duplicateRowNumbers.toString());
        }

        if (scoringStandardList.size() > 0) {
            for (ScoringStandard scoringStandard : scoringStandardList) {
                // 如果需要，可以在这里添加额外的逻辑，比如设置默认值或关联字段
                scoringStandardService.insertScoringStandard(scoringStandard);
            }
        }
        return AjaxResult.success();
    }

    /** 前端接口 ***************************************************************************************************/
    /** 前端接口 ***************************************************************************************************/
    /** 前端接口 ***************************************************************************************************/
}
